package com.zhongwang.mms.config.timingtask;

import com.zhongwang.mms.gen.entity.TCost;
import com.zhongwang.mms.gen.entity.TProject;
import com.zhongwang.mms.module.basic.dao.BoardDao;
import com.zhongwang.mms.module.overview.service.OverStatisticalService;
import com.zhongwang.mms.module.purchase.model.VWProject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.*;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;


@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling // 2.开启定时任务
@EnableAsync
@Component
/**
 * @ClassName： StatisticalTimingTask
 * @Description： 定时统计任务 不要删除 辛苦半个月的成果
 * @Author: 徐一贺
 * @Date: 2020/7/16 14:14
 **/
public class StatisticalTimingTask implements SchedulingConfigurer {

    @Autowired
    private BoardDao boardDao;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        Method[] methods = BatchProperties.Job.class.getMethods();
        int defaultPoolSize = 3;
        int corePoolSize = 0;
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                Scheduled annotation = method.getAnnotation(Scheduled.class);
                if (annotation != null) {
                    corePoolSize++;
                }
            }
            if (defaultPoolSize > corePoolSize) {
                corePoolSize = defaultPoolSize;
            }
        }
        taskRegistrar.setScheduler(new ScheduledThreadPoolExecutor(corePoolSize));
        //第一次启动更新内存
        updateCache();
    }

//    @Scheduled(cron = "0/5 30 23 28-31 * ?")
//    /**
//     * 执行定时计划
//     */
//    private void monthStatisticalData() {
//        final Calendar c = Calendar.getInstance();
//        //如果是是最后一天
//        if (c.get(Calendar.DATE) == c.getActualMaximum(Calendar.DATE)) {
//            overStatisticalService.execStatisticalPlan("timing_task_data");
//        }
//    }
    /** 全局变量，应用内随处可拿 项目表项目列表 */
    public static final List<VWProject> VWProjectCache = new CopyOnWriteArrayList<>();
    /** 全局变量，应用内随处可拿 成本项目表项目列表 */
    public static final List<TCost> TProjectCache = new CopyOnWriteArrayList<>();
    /**
     * 执行定时计划 每分钟将项目表的数据保存到内存当中
     */
    @Async
    @Scheduled(fixedDelay = 60_000)
    protected void loadMemoryData() {
        updateCache();
    }

    /**
     * 更新项目表和成本表缓存
     */
    private void updateCache(){
        List<VWProject> list = boardDao.selectProjectList();
        boolean VWProjectCacheIsNeedUpdate = isVwProjectCacheIsNeedUpdate(list);
        if (VWProjectCacheIsNeedUpdate) {
            VWProjectCache.clear();
            VWProjectCache.addAll(list);
        }
        List<TCost> tlist = boardDao.selectCost();
        boolean TProjectCacheIsNeedUpdate = isTProjectCacheIsNeedUpdate(tlist);
        if (TProjectCacheIsNeedUpdate) {
            TProjectCache.clear();
            TProjectCache.addAll(tlist);
        }
    }

    /**
     * 判断是否需要更新成本项目号缓存
     * @param tlist
     * @return
     */
    public static boolean isTProjectCacheIsNeedUpdate(List<TCost> tlist) {
        boolean TProjectCacheIsNeedUpdate = false;
        if (tlist.size() != TProjectCache.size()) {
            TProjectCacheIsNeedUpdate = true;
        }else{
            for (int i = 0; i < TProjectCache.size(); i++) {
                TCost tcost = TProjectCache.get(i);
                TCost tCostProject = tlist.get(i);
                if (!tcost.getCosProCode().equals(tCostProject.getCosProCode()) || !tcost.getCosProName().equals(tCostProject.getCosProName())) {
                    TProjectCacheIsNeedUpdate = true;
                    break;
                }
            }
        }
        return TProjectCacheIsNeedUpdate;
    }

    /**
     * 判断是否更新项目号表缓存
     * @param list
     * @return
     */
    public static boolean isVwProjectCacheIsNeedUpdate(List<VWProject> list) {
        boolean VWProjectCacheIsNeedUpdate = false;
        if(list.size() != VWProjectCache.size()) {
            VWProjectCacheIsNeedUpdate = true;
        }else{
            for (int i = 0; i < VWProjectCache.size(); i++) {
                VWProject vwProject =  VWProjectCache.get(i);
                VWProject project = list.get(i);
                if (!vwProject.getCode().equals(project.getCode()) || !vwProject.getName().equals(project.getName())) {
                    VWProjectCacheIsNeedUpdate = true;
                    break;
                }
            }
        }
        return VWProjectCacheIsNeedUpdate;
    }

    /**
     * 根据项目号获取成本项目信息
     * @param code
     * @return
     */
    public static TCost getCBZXProject(String code){
        for (TCost tcost : TProjectCache) {
            if (code.equals(tcost.getCosProCode())){
                return tcost;
            }
        }
        return null;
    }

    /**
     * 根据项目号获取项目信息
     * @param code 项目号
     * @return 项目信息
     */
    public static VWProject getVWProjectByCode(String code){
        for (VWProject vwProject : VWProjectCache) {
            if(code.equals(vwProject.getCode())){
                return vwProject;
            }
        }
        return null;
    }
}
 